/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.system.service.impl;


import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.system.domain.DictData;
import com.koron.system.domain.DictType;
import com.koron.system.mapper.DictDataMapper;
import com.koron.system.mapper.DictTypeMapper;
import com.koron.system.service.api.DictTypeService;
import com.koron.system.utils.BusinessCode;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DictTypeServiceImpl implements DictTypeService {

    private final static  Logger logger = LoggerFactory.getLogger(DictTypeServiceImpl.class);

    @Override
    public MessageBean<Integer> saveDictType(DictType dictType) {
        MessageBean<Integer> msg = new MessageBean<>();
        SessionFactory factory = new SessionFactory();
        DictTypeMapper mapper = factory.getMapper(DictTypeMapper.class);
        try {
            Integer value = 0;
            if (StringUtils.isEmpty(dictType.getId())) {
                //新增操作
                dictType.setId(DefaultIdGenerator.getInstance().generateLongId());
                //判断类型名称或者key是否唯一
                List<DictType> isExitList = mapper.queryByNameOrKey(dictType.getName(), dictType.getDictKey());
                if (isExitList.size() > 0) {
                    msg.setCode(BusinessCode.DICTTYPE_DUBLE_NAME_OR_KEY.getCode());
                    msg.setDescription(BusinessCode.DICTTYPE_DUBLE_NAME_OR_KEY.getDescription());
                    return msg;
                }
                dictType.setId(DefaultIdGenerator.getInstance().generateLongId());
                dictType.setAddTime(dictType.getUpdateTime());
                dictType.setAddUser(dictType.getUpdateUser());
                value = mapper.insert(dictType);
            } else {
                //修改操作
                //判断修改的记录是否存在
                DictType type = mapper.queryOne(dictType.getId());
                if (null == type) {
                    msg.setCode(BusinessCode.DICTTYPE_UPDATE_DATA_NOT_FOUND.getCode());
                    msg.setDescription(BusinessCode.DICTTYPE_UPDATE_DATA_NOT_FOUND.getDescription());
                    return msg;
                }
                dictType.setAddTime(type.getAddTime());
                dictType.setAddUser(type.getAddUser());
                //判断类型名称和key是否唯一
                List<DictType> isExitList = mapper.queryByNameOrKey(dictType.getName(), dictType.getDictKey());
                for (DictType en : isExitList) {
                    if (!en.getId().equals(dictType.getId())) {
                        msg.setCode(BusinessCode.DICTTYPE_DUBLE_NAME_OR_KEY.getCode());
                        msg.setDescription(BusinessCode.DICTTYPE_DUBLE_NAME_OR_KEY.getDescription());
                        return msg;
                    }
                }
                value = mapper.update(dictType);
            }
            factory.close();
            if (value > 0) {
                msg.setCode(BusinessCode.SUCCESS.getCode());
                msg.setDescription("保存字典类型成功");
                msg.setData(value);
                return msg;
            } else {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("保存字典类型失败");
                return msg;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            if (null != factory) {
                factory.close(false);
            }
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }finally {
            if (null != factory) {
                factory.close();
            }
        }
    }

    @Override
    public MessageBean<Integer> batchUpateDictType(List<DictType> dictTypeList) {
        MessageBean<Integer> msg = new MessageBean<>();
        SessionFactory factory = new SessionFactory();
        DictTypeMapper mapper = factory.getMapper(DictTypeMapper.class);
        try {
            int i = 0;
            for (DictType dictType : dictTypeList) {
                for (int j = dictTypeList.size() - 1; j > i; j++) {
                    if (StringUtils.isNotEmpty(dictTypeList.get(j).getName()) && StringUtils.isNotEmpty(dictType.getName())) {
                        if (!dictTypeList.get(j).getId().equals(dictType.getId()) &&
                                dictTypeList.get(j).getName().equals(dictType.getName())) {
                            msg.setCode(BusinessCode.DICTTYPE_DUBLE_NAME_OR_KEY.getCode());
                            msg.setDescription(BusinessCode.DICTTYPE_DUBLE_NAME_OR_KEY.getDescription());
                            return msg;
                        }
                    }
                    if (StringUtils.isNotEmpty(dictTypeList.get(j).getDictKey()) && StringUtils.isNotEmpty(dictType.getDictKey())) {
                        if (!dictTypeList.get(j).getId().equals(dictType.getId()) &&
                                dictTypeList.get(j).getDictKey().equals(dictType.getDictKey())) {
                            msg.setCode(BusinessCode.DICTTYPE_DUBLE_NAME_OR_KEY.getCode());
                            msg.setDescription("字典类型key要求唯一，但修改的数据中存在重复");
                            return msg;
                        }
                    }
                }
                //判断类型名称和key是否唯一
                List<DictType> isExitList = mapper.queryByNameOrKey(dictType.getName(), dictType.getDictKey());
                for (DictType en : isExitList) {
                    if (!en.getId().equals(dictType.getId())) {
                        msg.setCode(BusinessCode.DICTTYPE_DUBLE_NAME_OR_KEY.getCode());
                        msg.setDescription("批量修改的字典类型名称或者key与已存在的字典类型数据重复");
                        return msg;
                    }
                }
                i++;
            }
            //校验通过，进行批量修改
            Integer value = mapper.batchUpdate(dictTypeList);
            List<DictType> clonList = cloneType(dictTypeList);
            factory.close();
            if (value > 0) {
                msg.setCode(BusinessCode.SUCCESS.getCode());
                msg.setDescription("批量修改字典类型数据成功");
                return msg;
            } else {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("批量修改字典类型数据失败");
                return msg;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            if (null != factory) {
                factory.close(false);
            }
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }finally {
            if (null != factory) {
                factory.close();
            }
        }
    }

    @Override
    public MessageBean<Integer> batchDeteleDictType(List<String> idList) {
        MessageBean<Integer> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            DictTypeMapper typeMapper = factory.getMapper(DictTypeMapper.class);
            DictDataMapper dataMapper = factory.getMapper(DictDataMapper.class);
            StringBuilder description1 = new StringBuilder();
            List<String> delIdList = new ArrayList<>();
            for (String id : idList) {
                DictType type = typeMapper.queryOne(id);
                if (null != type) {
                    List<DictData> list = dataMapper.queryAll(null, type.getDictKey(), null, null);
                    if (null != list && list.size() > 0) {
                        description1.append(id);
                    } else {
                        delIdList.add(id);
                    }
                }
            }
            if (null == delIdList || delIdList.size() <= 0) {
                msg.setCode(BusinessCode.DICTTYPE_DELETE_HAVE_DATA.getCode());
                msg.setDescription(BusinessCode.DICTTYPE_DELETE_HAVE_DATA.getDescription());
                return msg;
            }
            Integer value = typeMapper.batchDetele(delIdList);
            if (value > 0) {
                msg.setData(value);
                msg.setCode(BusinessCode.SUCCESS.getCode());
                String desciption = "删除字典类型成功";
                if (StringUtils.isNotEmpty(description1.toString())) {
                    description1.append("下有字典数据，无法执行删除操作");
                    desciption += "其中id为：" + description1.toString();
                }
                msg.setDescription(desciption);
                return msg;
            } else {
                msg.setData(BusinessCode.FAILURE.getCode());
                msg.setCode(0);
                msg.setDescription("删除字典类型失败");
                return msg;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }

    }

    @Override
    public MessageBean<DictType> queryOneDictType(String id) {
        MessageBean<DictType> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory();) {
            DictType entity = factory.getMapper(DictTypeMapper.class).queryOne(id);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("获取字典类型详情成功");
            msg.setData(entity);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    @Override
    public MessageBean<DataBean<DictType>> queryAllDictType(Integer start, Integer rows) {
        MessageBean<DataBean<DictType>> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory();) {
            DictTypeMapper mapper = factory.getMapper(DictTypeMapper.class);
            List<DictType> list = mapper.queryAll(null, start, rows);
            Integer totalNumber = mapper.countTotal();
            rows = rows == null ? totalNumber : (rows <= 0 ? 1 : rows);
            Integer totalPage = totalNumber > rows ? (totalNumber % rows == 0 ? totalNumber / rows : totalNumber / rows + 1) : 1;
            DataBean<DictType> dataBean = new DataBean<>();
            dataBean.setList(list);
            dataBean.setTotalNumber(totalNumber);
            dataBean.setTotalPage(totalPage);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("查询字典类型列表成功");
            msg.setData(dataBean);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }

    }

    @Override
    public MessageBean<List<DictType>> getDictTypesAndDictDatas(String name) {
        MessageBean<List<DictType>> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            DictTypeMapper mapper = factory.getMapper(DictTypeMapper.class);
            DictDataMapper dataMapper = factory.getMapper(DictDataMapper.class);
            List<DictType> typeList = mapper.queryAll(name, null, null);
            List<DictData> dataList = dataMapper.queryAll(null, null, null, null);
            if (null != typeList && !typeList.isEmpty()) {
                List<DictType> cloneTypeList = cloneType(typeList);
                List<DictData> cloneDataList = cloneDictData(dataList);
                construct(cloneTypeList, cloneDataList);
                msg.setData(cloneTypeList);
            }
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("查询字典数据类型和类型下的字典数据成功");
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    private void construct(List<DictType> typeList, List<DictData> items) {
        for (DictType root : typeList) {
            List<DictData> collect = (items == null || items.size() <= 0) ? new ArrayList<>() : items.stream().filter(item -> item.getDictKey().equals(root.getDictKey())).collect(Collectors.toList());
            if (null != collect && !collect.isEmpty()) {
                collect.sort(Comparator.comparing(DictData::getDictIndex));
                root.setDataList(collect);
            }
        }
    }


    private List<DictType> cloneType(List<DictType> sources) {
        List<DictType> cloneList = new ArrayList<>();
        sources.stream().forEach(source -> {
            try {
                DictType dest = new DictType();
                PropertyUtils.copyProperties(dest, source);
                cloneList.add(dest);
            } catch (Exception e) {
                logger.error(e.getMessage(),e);
            }
        });
        return cloneList;
    }

    private List<DictData> cloneDictData(List<DictData> sources) {
        List<DictData> cloneList = new ArrayList<>();
        sources.stream().forEach(source -> {
            try {
                DictData dest = new DictData();
                PropertyUtils.copyProperties(dest, source);
                cloneList.add(dest);
            } catch (Exception e) {
                logger.error(e.getMessage(),e);
            }
        });
        return cloneList;
    }

}
